home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_02_07 / 2n07032a < prev    next >
Text File  |  1991-05-31  |  14KB  |  367 lines

  1.  
  2. /***************************************************************************/
  3. /* function main                                                           */
  4. /***************************************************************************/
  5. int main (int argc, char *argv[])
  6. {
  7.    union REGS Myregs;
  8.  
  9.    if (argc < 2) {
  10.       fprintf (stderr,
  11.             "This program sends the contents of an HPFS file to standard\n"
  12.             "output.  This may be piped to a file or device.\n"
  13.             "Usage:  getfile <filename>\n"
  14.             "where <filename is a fully qualified path without a drive\n"
  15.             "specification.\n");
  16.       exit (NO_ARG);
  17.    }
  18.    setmode (STDOUT, (int) O_BINARY);
  19.    Myregs.x.ax = 0x4400;               // IOCtl Get Data
  20.    Myregs.x.bx = STDOUT;
  21.    intdos (&Myregs, &Myregs);
  22.    Myregs.h.dh = 0;
  23.    Myregs.h.dl |= 0x20;                // Set raw mode
  24.    Myregs.x.ax = 0x4401;               // IOCtl Set Data
  25.    intdos (&Myregs, &Myregs);
  26.    GetBootRecords ();
  27.    GetRootDir ();
  28.    FindFileFnode (strupr(argv[1]));    // FileFnode will contain file fnode
  29.    DoFewFrags (&FileFnode.FewFragsFnode);
  30.    return (0);
  31. }
  32. //
  33.  
  34. /***************************************************************************/
  35. /* function GetBootRecords                                                 */
  36. /***************************************************************************/
  37. void GetBootRecords ()
  38. {
  39.    PartitionEntry *ThisPartition;
  40.    unsigned MoreCyl;
  41.  
  42.    DiskInfo.drive = FIXED_DRIVE;
  43.    DiskInfo.nsectors = 1;
  44.    DiskInfo.head = 0;
  45.    DiskInfo.track = 0;
  46.    DiskInfo.sector = 1;
  47.    DiskInfo.buffer = &VolumeBootSector;
  48.    _bios_disk_with_retry (&DiskInfo);
  49.    HPFSPartition = NULL;
  50.    for (ThisPartition = VolumeBootSector.Partitions;
  51.          ThisPartition <= &VolumeBootSector.Partitions[3];
  52.          ThisPartition++)
  53.       if (ThisPartition->SysInd == HPFS_PART) {
  54.          HPFSPartition = ThisPartition;
  55.          break;
  56.       }
  57.    if (HPFSPartition == NULL) {
  58.       fprintf (stderr, "No HPFS partition found, aborting...\n");
  59.       exit (BAD_DISK);
  60.    }
  61.    DiskInfo.head = HPFSPartition->BH;
  62.    MoreCyl = HPFSPartition->BS & 0xC0;
  63.    MoreCyl = MoreCyl << 2;
  64.    DiskInfo.track = HPFSPartition->BCyl + MoreCyl;
  65.    DiskInfo.sector = HPFSPartition->BS & 0x3F;
  66.    DiskInfo.buffer = &PartitionBootSector;
  67.    _bios_disk_with_retry (&DiskInfo);
  68.  
  69.    BytesPerSector = PartitionBootSector.BytesPerSector;
  70.    SectorsInSegment = (USHORT) (0x10000UL / (ULONG) BytesPerSector);
  71.    HugeShift = 0x1000;
  72.    SectorsInFullTrack = PartitionBootSector.SectorsInTrack *
  73.                         PartitionBootSector.NumOfHeads;
  74. }
  75. //
  76.  
  77. /***************************************************************************/
  78. /* function GetRootDir                                                     */
  79. /* Correct for OS/2 1.2 on ST-251 disk                                     */
  80. /***************************************************************************/
  81. void GetRootDir (void)
  82. {
  83.    GetRelativeSectors (SUPER_BLOCK, 1, &SuperBlock);
  84.    GetRelativeSectors (SuperBlock.RootDirFnode, 1, &DirFnode);
  85.    RootDirSector = DirFnode.FragTable.FewFrags[0].ulFragSector;
  86. }
  87. //
  88.  
  89. /***************************************************************************/
  90. /* function FindFileFnode                                                  */
  91. /* Puts the file Fnode in FileFnode                                        */
  92. /***************************************************************************/
  93. void FindFileFnode (char *Fname)
  94. {
  95.    USHORT flast;
  96.  
  97.    GetRelativeSectors (RootDirSector, 4, &DirectoryCluster);
  98.    flast = strlen (Fname) - 1;
  99.    if (Fname[flast] == '.')         // OS/2 directories do not contain ending
  100.       Fname[flast] = 0;             //    period of file names
  101.    FindFile (Fname);
  102.    FileSize = FileFnode.FewFragsFnode.ulcFileLength;
  103. }
  104. //
  105.  
  106. /***************************************************************************/
  107. /* function FindFile                                                       */
  108. /***************************************************************************/
  109. void FindFile (const char *path)
  110. {
  111.    char PathCopy [_MAX_PATH];
  112.    char Element [_MAX_FNAME];
  113.    BOOL Result;
  114.    DirEntryType *CurrDirEntry;
  115.    RSN SectorNum;
  116.  
  117.    Level++;
  118.    _fstrcpy (PathCopy, path); /* Make local copy */
  119.    MakeFilename (PathCopy, PathCopy, Element); /* Split and update */
  120.    if (PathCopy[0])                       // At least '\' left in path
  121.       PathCopy[strlen (PathCopy) - 1] = 0;// Erase the '\'
  122.    if (PathCopy[0] != 0)                  // More than '\'
  123.       FindFile (PathCopy);                // continue recursively
  124.    Result = FindDirEntry (Element, &CurrDirEntry);
  125.    if (Result != TRUE) {
  126.       fprintf (stderr, "Could not find %s, aborting...\n", path);
  127.       exit (NO_FILE);
  128.    }
  129.    if (Level > 1) {                       // Directory
  130.       if ((CurrDirEntry->bFlags & FLAG_DIR) == 0) {
  131.          fprintf (stderr, "%s is a file, not a directory. Aborting...\n",
  132.                   path);
  133.          exit (NO_FILE);
  134.       }
  135.    } else { /* File name */
  136.       if ((CurrDirEntry->bFlags & FLAG_DIR) != 0) {
  137.          fprintf (stderr, "%s is a directory, not a file. Aborting...\n",
  138.                   path);
  139.          exit (NO_FILE);
  140.       }
  141.    }
  142.    if (Level > 1) {                       // Directory fnode
  143.       GetRelativeSectors (CurrDirEntry->ulPointedSector, 1, &DirFnode);
  144.       SectorNum = DirFnode.FragTable.FewFrags[0].ulFragSector;
  145.       GetRelativeSectors (SectorNum, 4, &DirectoryCluster); // Directory body
  146.    } else
  147.       GetRelativeSectors (CurrDirEntry->ulPointedSector, 1, &FileFnode);
  148.    Level--;
  149. }
  150. //
  151.  
  152. /***************************************************************************/
  153. /* function FindDirEntry                                                   */
  154. /* Assumes that correct directory cluster is in DirectoryCluster
  155.   */
  156. /***************************************************************************/
  157. BOOL FindDirEntry (char *EntryName, DirEntryType **Location)
  158. {
  159.    BYTE EntryNameLength, CmpLen;
  160.    DirEntryType *TmpLoc;
  161.    int UpDownLen, UpDown;
  162.    RSN SectorNum;
  163.  
  164.    EntryNameLength = (BYTE) strlen (EntryName);
  165.    for (TmpLoc = &DirectoryCluster.FirstDirEntry;;) {
  166.       if (EntryNameLength > TmpLoc->bcNameLength) { // Compare lengths
  167.          CmpLen = TmpLoc->bcNameLength;
  168.          UpDownLen = UP;
  169.       } else {
  170.          CmpLen = EntryNameLength;
  171.          if (EntryNameLength < TmpLoc->bcNameLength)
  172.             UpDownLen = DOWN;
  173.          else
  174.             UpDownLen = SAME;
  175.       }
  176.       UpDown = memcmp (EntryName, TmpLoc->bName, CmpLen); // Compare contents
  177.       if (UpDown == SAME)                                // Contents same
  178.          UpDown = UpDownLen;                             // Judge by length
  179.       if (UpDown == SAME) {                              // Identical
  180.          *Location = TmpLoc;
  181.          return (TRUE);
  182.       }                                                  // Where to look now?
  183.       if (UpDown < 0) {                                  // Try down?
  184.          if ((TmpLoc->bSplitFlag & DIR_SPLITS) == 0)     // No connection
  185.             return (FALSE);                              //    File not there
  186.          SectorNum = *(RSN *)                         // Find connection
  187.                       (((BYTE *) TmpLoc) + TmpLoc->uscDirEntrySize - 4);
  188.          GetRelativeSectors (SectorNum, 4, &DirectoryCluster);
  189.          TmpLoc = &DirectoryCluster.FirstDirEntry;
  190.          continue;
  191.       }                                                  // Try same level
  192.       if ((TmpLoc->bSplitFlag & END_OF_DIR) != 0)        // No more here
  193.          return (FALSE);                                 //    File not there
  194.       TmpLoc = (DirEntryType *)                          // Next Entry
  195.                 (((BYTE *) TmpLoc) + TmpLoc->uscDirEntrySize);
  196.    }
  197. }
  198. //
  199.  
  200. /***************************************************************************/
  201. /* function MakeFileName                                                   */
  202. /*****************************